﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Web;
using System.IO;

namespace lzsoft.CDN
{
    public class HttpSocket
    {
        int port = 80;
        string urlpath, domain, serverIp, localPath;
        Socket socket;
        IPEndPoint ipEnd;
        StringBuilder buf = new StringBuilder(100);
        byte[] data = new byte[1024];
        byte[] ms;
        FileStream stream;

        public HttpSocket(string urlpath, string domain, string serverIp, string localPath)
        {
            this.urlpath = urlpath;
            this.domain = domain;
            this.serverIp = serverIp;
            this.localPath = localPath;
        }

        protected virtual void CreateFile()
        {
            FileInfo fi = new FileInfo(localPath);
            if (!fi.Directory.Exists)
            {
                fi.Directory.Create();
            }
            stream = File.Open(localPath, FileMode.Create);
        }

        protected virtual void BuilderHead()
        {
            #region 组装HTTP请求
            //这里请求的相对地址
            buf.Append("GET ").Append(urlpath).Append(" HTTP/1.1").Append("\r\n");
            buf.Append("Host:").Append(domain).Append("\r\n");
            buf.Append("Connection:close").Append("\r\n");//keep-alive
            buf.Append("Cache-Control:max-age=0").Append("\r\n");
            buf.Append("Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8").Append("\r\n");
            buf.Append("Origin:http://b2c.upin7.com").Append("\r\n");
            buf.Append("User-Agent:Mozilla/5.0 (Windows NT 5.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36").Append("\r\n");
            buf.Append("Content-Type:application/x-www-form-urlencoded").Append("\r\n");            
            buf.Append("Accept-Encoding:gzip,deflate,sdch").Append("\r\n");
            buf.Append("Accept-Language:zh-CN,zh;q=0.8,en;q=0.6").Append("\r\n\r\n");

            ms = System.Text.UTF8Encoding.UTF8.GetBytes(buf.ToString());

            #endregion
        }

        protected virtual void BuilderSocket()
        {
            //得到所访问的网址的IP地址
            IPAddress ip = IPAddress.Parse(serverIp);
            ipEnd = new IPEndPoint(ip, port);
            //使用tcp协议 stream类型 （IPV4）
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //socket.ReceiveTimeout = 1000;
        }

        protected void Connect()
        {
                socket.Connect(ipEnd);
        }
        protected void HttpSend()
        {
            //发送
            socket.Send(ms);
            int recv = 0;
            bool istart = false;
            do
            {
                recv = socket.Receive(data);
                //如果请求的页面meta中指定了页面的encoding为gb2312则需要使用对应的Encoding来对字节进行转换
                //list.Text += (Encoding.UTF8.GetString(data, 0, recv));
                //re.Append(Encoding.Default.GetString(data, 0, recv));
                int start = 0;
                if (!istart)
                {
                    for (int i = 0; i < recv; i++)
                    {
                        if (i + 4 < recv &&
                            data[i] == '\r' &&
                            data[i + 1] == '\n' &&
                            data[i + 2] == '\r' &&
                            data[i + 3] == '\n')
                        {
                            start = i + 4;
                            istart = true;
                            break;
                        }
                    }
                }
                if (istart)
                {
                    stream.Write(data, start, recv - start);
                }
            } while (recv != 0);
            //禁用上次的发送和接受
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
            stream.Close();
        }

        public void SaveStream()
        {
            BuilderSocket();
            BuilderHead();
            Connect();
            CreateFile();
            HttpSend();
            ValidateFile();
        }
        protected void ValidateFile()
        {
            var bytes = new byte[4];
            var f = File.OpenRead(localPath);
            f.Read(bytes, 0, 4);
            f.Close();
            if (!ImageFormat.Validate(ref bytes))
            {
                File.Delete(localPath);
            }
        }
    }
}